#include "Parser.h"

namespace Pomian
{

	AstNode* Number::parse(Tokenizer* tokenizer)
	{
		if (tokenizer->has(1) == false) 
		{
			return nullptr;
		}
		NumberToken* numberToken = dynamic_cast<NumberToken*>(tokenizer->current(0));
		if (numberToken == nullptr)
		{
			return nullptr;
		}
		tokenizer->move(1);
		return new NumberNode(numberToken);
	}

	
	AstNode* Identifier::parse(Tokenizer* tokenizer)
	{
		if (tokenizer->has(1) == false)
		{
			return nullptr;
		}
		IToken* token = tokenizer->current(0);
		IdentifierToken* identifierToken = dynamic_cast<IdentifierToken*>(token);
		if (identifierToken == nullptr)
		{
			return nullptr;
		}
		tokenizer->move(1);
		return new IdentifierNode(identifierToken);
	}

	Keyword::Keyword(const std::string& keyword)
		: m_keyword(keyword)
	{
	}

	AstNode* Keyword::parse(Tokenizer* tokenizer)
	{
		if (tokenizer->has(1) == false)
		{
			return nullptr;
		}
		IToken* token = tokenizer->current(0);
		KeywordToken* keywordToken = dynamic_cast<KeywordToken*>(token);
		if (keywordToken == nullptr)
		{
			return nullptr;
		}		
		if (m_keyword != keywordToken->toWord()) 
		{
			return nullptr;
		}
		tokenizer->move(1);
		return new KeywordNode(keywordToken);
	}

	Keyword* createKeyword(const std::string& keyword)
	{
		return new Keyword(keyword);
	}

	Flag::Flag(FlagToken* token)
		: m_token(token)
	{
	}
	AstNode* Flag::parse(Tokenizer* tokenizer)
	{
		if (tokenizer->has(1) == false)
		{
			return nullptr;
		}
		FlagToken* flagToken = dynamic_cast<FlagToken*>(tokenizer->current(0));
		if (flagToken == nullptr)
		{
			return nullptr;
		}
		if (m_token != flagToken)
		{
			return nullptr;
		}
		tokenizer->move(1);
		return new FlagNode(flagToken);
	}

	Flag* createEoL()
	{
		return new Flag(FlagToken::EoL);
	}
	

	Flag* createEoF()
	{
		return new Flag(FlagToken::EoF);
	}

	Operator::Operator(const std::set<std::string>& operators)
		: m_operators(operators)
	{
	}

	AstNode* Operator::parse(Tokenizer* tokenizer)
	{
		if (tokenizer->has(1) == false)
		{
			return nullptr;
		}
		OperatorToken* operatorToken = dynamic_cast<OperatorToken*>(tokenizer->current(0));
		if (operatorToken == nullptr)
		{
			return nullptr;
		}
		if (m_operators.find(operatorToken->toWord()) == m_operators.cend())
		{
			return nullptr;
		}
		tokenizer->move(1);
		return new OperatorNode(operatorToken);
	}

	Seperator::Seperator(const std::string& seperator)
		: m_seperator(seperator)
	{
	}

	AstNode* Seperator::parse(Tokenizer* tokenizer)
	{
		if (tokenizer->has(1) == false)
		{
			return nullptr;
		}
		SeperatorToken* seperatorToken = dynamic_cast<SeperatorToken*>(tokenizer->current(0));
		if (seperatorToken == nullptr)
		{
			return nullptr;
		}
		if (m_seperator != seperatorToken->toWord())
		{
			return nullptr;
		}
		tokenizer->move(1);
		return new SeperatorNode(seperatorToken);
	}

	Number* createNumber()
	{
		return new Number();
	}

	Identifier* createIdentifier()
	{
		return new Identifier();
	}

	Operator* createOperator(const std::set<std::string>& operators)
	{
		return new Operator(operators);
	}

	Seperator* createSeperator(const std::string& seperator)
	{
		return new Seperator(seperator);
	}

}